/*
 * ComponentManager.cpp
 *
 * 11 de outubro de 2008
 */

#include "ComponentManager.h"
#include "Component.h"
#include "Container.h"
#include <vector>

namespace gui
  {
    ComponentManager* ComponentManager::_instance;

    ComponentManager::ComponentManager() 
      {
        _previous_mouse_b = _count = 0; 
      }
    
    ComponentManager* ComponentManager::instance()
      {
        if (_instance == NULL)
          { 
            _instance = new ComponentManager();
          }
        return _instance;
      }

    void ComponentManager::init() 
      { 
        move(0,0);
        size(SCREEN_W, SCREEN_H);
        _mask = create_bitmap(SCREEN_W, SCREEN_H); 
      }

    void ComponentManager::process()
      {
        checkFocus();

        std::vector<Component*>::iterator iter;
        for (iter = _content.begin(); iter != _content.end(); iter++)
          {
            (*iter)->process();
          }
      }

    void ComponentManager::checkFocus()
      {
        int i;
        
        if (mouse_b)
          {
            if (!_previous_mouse_b)
              {
                focus(hitTest(mouse_x, mouse_y));
              }
          }
        _previous_mouse_b = mouse_b;
      }

    void ComponentManager::paint(BITMAP* buffer)
      {
        paint(buffer, 0, 0);
        mask(_mask, 0, 0);
      }

    void ComponentManager::paint(BITMAP* buffer, int x_offset, int y_offset)
      {
        std::vector<Component*>::iterator iter;
        for (iter = _content.begin(); iter != _content.end(); iter++)
          {
            (*iter)->paint(buffer, x() + x_offset, y() + y_offset);
          }
      }

    void ComponentManager::mask(BITMAP* buffer, int x_offset, int y_offset)
      {
        std::vector<Component*>::iterator iter;
        for (iter = _content.begin(); iter != _content.end(); iter++)
          {
            (*iter)->mask(buffer, x() + x_offset, y() + y_offset);
          }
      }

    Component* ComponentManager::hitTest(int x, int y) const
      {
        int hit_id;
        hit_id = getpixel(_mask, x, y);
        return hitTest(this, hit_id, x, y);
      }

    Component* hitTest(Container* container, int hit_id, int x, int y) const
      {
        int i;
        Component* comp;
        Component* ret = NULL;

        for (i = 0; (ret == NULL) && (i < container->count()); i++)
          {
            comp = container->get(i);
            if (comp->id() == hit_id)
              {
                ret = comp;
              }
            else if (dynamic_cast<Container*>(comp))
              {
                ret = hitTest(comp, x, y);
              }
          }

        return ret;
      }

    Component* ComponentManager::focused() const
      {
        return _focused;
      }
    
    bool const ComponentManager::focus(Component* comp)
      {
        _focused = comp;
        return _focused != NULL;
      }
  }

